package com.edu.order.controller;

import com.edu.api.entity.common.JwtUtil;
import com.edu.api.entity.common.TimeUtil;
import com.edu.api.entity.order.PayConfig;
import com.edu.order.service.*;
import com.github.wxpay.sdk.WXPayUtil;
import com.jfinal.kit.HttpKit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;


/**
 * @description: 描述
 * @author: xnylh
 * @createDate: 2023/1/9 0009 20:55
 */
@RestController
@RequestMapping("userCourseOrder")
public class UserCourseOrderController {

    @Autowired
    private UserCourseOrderService userCourseOrderService;

    @Autowired
    private PayOrderRecordService payOrderRecordService;

    @Autowired
    CourseFeign courseFeign;

    @Autowired
    private PayOrderService payOrderService;

    @Autowired
    private WeChatPayRabbitmq weChatPayRabbitmq;

    private String fromStatus = "CREATE";

    @GetMapping("/deleteOrder")
    public Object deleteOrder(String orderId,HttpServletRequest request) throws Exception {
        //1.编写商户信息
        Map<String,String> mm = new HashMap();
        mm.put("appid",PayConfig.appid); //公众账号ID
        mm.put("mch_id",PayConfig.partner);//商户号
        mm.put("out_trade_no",orderId);//订单编号
        mm.put("nonce_str",WXPayUtil.generateNonceStr()); //随机字符串
        System.out.println(mm);
        //2.生成数字签名,并把上面的map转换成xml格式
        String xml = WXPayUtil.generateSignedXml(mm, PayConfig.partnerKey);
        System.out.println(xml);

        //3.将数据发送给微信后台,并得到微信后台返回的数据
        String url = "https://api.mch.weixin.qq.com/pay/orderquery";
        String result = HttpKit.post(url, xml);
//            System.out.println(result);//报错：<![CDATA[签名错误]]>

        //`去微信撤销订单`
        url = "https://api.mch.weixin.qq.com/pay/closeorder";
        String resultReverse = HttpKit.post(url, xml);
        WXPayUtil.xmlToMap(resultReverse);

        //4.后台返回的xml格式，转成map，并添加两个参数
        Map<String, String> resultMap = WXPayUtil.xmlToMap(result);
        userCourseOrderService.updateUserCourseOrder(orderId, (byte) 30);
        payOrderRecordService.addPayOrderRecord(orderId,"CANCEL",fromStatus,JwtUtil.getMemberIdByJwtToken(request),"0");
        return resultMap;
    }


    /**
     * 生成二维码
     * @param courseid
     * @param coursename
     * @param price
     * @param request
     * @return
     * @throws Exception
     */
    @GetMapping("createCode")
    public Object createCode(String courseid,String coursename, String price,HttpServletRequest request) throws Exception {

        //1.编写商户信息
        Map<String,String> mm = new HashMap();
        mm.put("appid", PayConfig.appid); //公众账号ID
        mm.put("mch_id",PayConfig.partner);//商户号
        mm.put("nonce_str", WXPayUtil.generateNonceStr());//随机字符串
        mm.put("body",coursename); //商品名称
        String orderId = WXPayUtil.generateNonceStr();
//        System.out.println("订单编号 = "+orderId);
        mm.put("out_trade_no",orderId); //商户订单号
        mm.put("total_fee",price+""); //订单金额,单位分
        mm.put("spbill_create_ip","127.0.0.1"); //终端IP
        mm.put("notify_url",PayConfig.notifyurl); //通知地址
        mm.put("trade_type","NATIVE"); //交易类型
//        System.out.println("发送的map = "+mm.toString());

        //2.生成数字签名,并把上面的map转换成xml格式
        String xml = WXPayUtil.generateSignedXml(mm,PayConfig.partnerKey);
//        System.out.println("转换后的xml = "+xml);

        //3.将数据发送给微信后台,并得到微信后台返回的数据
        String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        String result = HttpKit.post(url,xml);
//        System.out.println("返回的xml = "+result); //如果报错：<![CDATA[签名错误]]> 商户四要素的原因，重置商户API密钥。

        //4.后台返回的xml格式，转成map，并添加两个参数
        Map<String,String> resultMap = WXPayUtil.xmlToMap(result);
        resultMap.put("orderId",orderId);
        resultMap.put("money",price+"");
        // 查询订单状态需要订单编号，所以将订单编号保存并返回给前端
        resultMap.put("out_trade_no",mm.get("out_trade_no"));

        userCourseOrderService.insertCourseOrder(mm.get("out_trade_no"),Integer.valueOf(JwtUtil.getMemberIdByJwtToken(request)),Integer.parseInt(courseid));
        payOrderRecordService.addPayOrderRecord(mm.get("out_trade_no"),"CREATE",null,JwtUtil.getMemberIdByJwtToken(request),price);

//        userCourseOrderService.insertCourseOrder(orderId,Integer.valueOf(JwtUtil.getMemberIdByJwtToken(request)) ,Integer.valueOf(courseid));
//        payOrderRecordService.insertOrderRecord(orderId,Integer.valueOf(JwtUtil.getMemberIdByJwtToken(request)),null,"create",Integer.valueOf(price));
        //5.将map返回给浏览器
        return resultMap;
    }

    @GetMapping("checkOrderStatus")
    public Object checkOrderStatus(String orderId,String productId,String courseName,HttpServletRequest request) throws Exception {
        //1.编写商户信息
        Map<String,String> mm = new HashMap();
        mm.put("appid",PayConfig.appid); //公众账号ID
        mm.put("mch_id",PayConfig.partner);//商户号
        mm.put("out_trade_no",orderId);//订单编号
        mm.put("nonce_str",WXPayUtil.generateNonceStr()); //随机字符串
//        System.out.println(mm);
        //2.生成数字签名,并把上面的map转换成xml格式
        String xml = WXPayUtil.generateSignedXml(mm, PayConfig.partnerKey);
        System.err.println(xml);

        //3.将数据发送给微信后台,并得到微信后台返回的数据
        String url = "https://api.mch.weixin.qq.com/pay/orderquery";

        //第一次询问时间
        long beginTime = System.currentTimeMillis();
        int index = 0;
        weChatPayRabbitmq.getStateOfPayment(url,xml,productId,courseName,request);
        while(true) { //不停的去微信后台询问是否支付
            String result = HttpKit.post(url, xml);
//            System.out.println(result);//报错：<![CDATA[签名错误]]>

            //4.后台返回的xml格式，转成map，并添加两个参数
            Map<String, String> resultMap = WXPayUtil.xmlToMap(result);

            //5.将map转成json并返回给浏览器
            //未支付,修改状态继续询问。
            if(resultMap.get("trade_state").equalsIgnoreCase("NOTPAY") && index == 0){
                index++;
                fromStatus=resultMap.get("trade_state");
                userCourseOrderService.updateUserCourseOrder(orderId, (byte) 10);
                payOrderRecordService.addPayOrderRecord(orderId,"NOTPAY","CREATE",JwtUtil.getMemberIdByJwtToken(request), resultMap.get("total_fee"));
            }
            //已经成功支付，停止询问
            if(resultMap.get("trade_state").equalsIgnoreCase("success")){
                //支付成功并添加并修改表
                userCourseOrderService.updateUserCourseOrder(orderId, (byte) 20);
                payOrderRecordService.addPayOrderRecord(orderId,"PAY","NOTPAY",JwtUtil.getMemberIdByJwtToken(request), resultMap.get("total_fee"));
                payOrderService.insertPayOrder(orderId,Integer.valueOf(JwtUtil.getMemberIdByJwtToken(request)),
                        Integer.valueOf(productId), courseName,new BigDecimal(resultMap.get("total_fee")),
                        resultMap.get("fee_type"),resultMap.get("trade_type"),(byte)2,request.getRemoteAddr(), TimeUtil.getTimeDate(),resultMap.get("transaction_id"));
                courseFeign.updateSales(productId);
                return resultMap;
            }
            //超过30秒未支付，停止询问
            if(System.currentTimeMillis() - beginTime > 10000){
                //`去微信撤销订单`
                url = "https://api.mch.weixin.qq.com/pay/closeorder";
                String resultReverse = HttpKit.post(url, xml);
                resultMap = WXPayUtil.xmlToMap(resultReverse);

                userCourseOrderService.updateUserCourseOrder(orderId, (byte) 40);
                payOrderRecordService.addPayOrderRecord(orderId,"OVERDUE",fromStatus,JwtUtil.getMemberIdByJwtToken(request),"0");
                return resultMap;
            }
            Thread.sleep(3000); //每隔3秒，询问一次微信后台
        }
    }

    @RequestMapping("wxCallback")
    public String wxCallBack(HttpServletRequest request, HttpServletResponse response) throws IOException {
        InputStream inStream = null;
        ByteArrayOutputStream outSteam = null;
        String resultxml = null;
        try {
            inStream = request.getInputStream();
            outSteam = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
            }
            resultxml = new String(outSteam.toByteArray(), "utf-8");
        } catch (Exception e) {
            System.out.println("回调处理失败");
        }finally {
            if(null != outSteam) {
                outSteam.close();
            }
            if(null != inStream) {
                inStream.close();
            }
        }
        System.out.println("wxCallback - 回调请求参数:"+ resultxml);
        return resultxml;
    }
}